package com.luyuan.crm.sale.web;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

import org.hibernate.proxy.HibernateProxyHelper;
import org.springframework.beans.factory.InitializingBean;

import com.luyuan.crm.member.model.Address;
import com.luyuan.crm.member.model.Customer;
import com.luyuan.crm.member.model.Member;
import com.luyuan.crm.member.model.MemberIntegral;
import com.luyuan.crm.member.model.NoAccountCustomer;
import com.luyuan.crm.member.model.Region;
import com.luyuan.crm.member.service.CustomerService;
import com.luyuan.crm.member.service.MemberIntegralService;
import com.luyuan.crm.member.service.RegionService;
import com.luyuan.crm.sale.model.Delivery;
import com.luyuan.crm.sale.model.Order;
import com.luyuan.crm.sale.model.OrderType;
import com.luyuan.crm.sale.model.ProductOrder;
import com.luyuan.crm.sale.service.OrderService;
import com.luyuan.crm.sale.service.ProductOrderService;
import com.ruijie.foundation.international.MessageFormat;
import com.ruijie.util.StringUtils;
import com.ruijie.web.jsf.action.BaseAction;
import com.ruijie.web.jsf.action.WizardAction;

public class BaseOrderWizardAction extends BaseAction implements WizardAction, InitializingBean {

    @Resource(name = "customerService")
    protected CustomerService customerService;

    @Resource(name = "memberIntegralService")
    protected MemberIntegralService memberIntegralService;

    @Resource(name = "orderService")
    protected OrderService orderService;

    @Resource(name = "productOrderService")
    protected ProductOrderService productOrderService;

    @Resource(name = "regionService")
    private RegionService regionService;

    protected Order order;

    protected List<ProductOrder> products = new ArrayList<ProductOrder>();

    protected Customer customer;

    public void addProduct(ActionEvent actionEvent) {
        setRequestAttribute("products", products, true);
        setRequestAttribute("member", customer, true);
        setRequestAttribute("order", order, true);
    }

    public void deleteProductById(String id) {
        for (ProductOrder p : products) {
            if (p.getProduct().getId().equals(id)) {
                products.remove(p);
                break;
            }
        }
    }

    public void deleteProducts(ActionEvent event) {
        String[] selectedIds = getRequestParameterValues("product.id");
        if (selectedIds == null) {
            selectedIds = new String[0];
            addGlobalI18nMessage("请至少选择一条数据");
            return;
        }
        for (String id : selectedIds) {
            deleteProductById(id);
        }
    }

    public void saveProduct() {
        if (customer.getId() != null) {
            if (customer.getAddress() == null || StringUtils.isNullOrEmpty(customer.getAddress().getProvince())) {
                customer.setAddress(order.getDelivery().getDeliveryAddress());
            }
            else if (HibernateProxyHelper.getClassWithoutInitializingProxy(customer) != Member.class) {
                customer.setAddress(order.getDelivery().getDeliveryAddress());
                String phone = order.getDelivery().getDeliveryPhone();
                customer.setMobile(phone.split(",|，|、")[0]);
                customer.setName(order.getDelivery().getReceiver());
            }

            customerService.updateCustomer(customer);
        }
        else {
            if (HibernateProxyHelper.getClassWithoutInitializingProxy(order.getCustomer()) == Member.class) {
                NoAccountCustomer accountCustomer = new NoAccountCustomer();
                accountCustomer.setAccountHolder((Member) order.getCustomer());
                if (customer.getAddress() != null) {
                    accountCustomer.setAddress(customer.getAddress());
                }
                else {
                    accountCustomer.setAddress(order.getDelivery().getDeliveryAddress());
                }
                if (StringUtils.isNotEmpty(customer.getMobile())) {
                    accountCustomer.setMobile(customer.getMobile());
                }
                else {
                    String phone = order.getDelivery().getDeliveryPhone();
                    accountCustomer.setMobile(phone.split(",|，|、")[0]);
                }
                if (StringUtils.isNotEmpty(customer.getName())) {
                    accountCustomer.setName(customer.getName());
                }
                else {
                    accountCustomer.setMobile(order.getDelivery().getReceiver());
                }
                accountCustomer.setBirthDate(customer.getBirthDate());
                accountCustomer.setEmail(customer.getEmail());
                accountCustomer.setGender(customer.getGender());
                accountCustomer.setHeight(customer.getHeight());
                accountCustomer.setWeight(customer.getWeight());
                accountCustomer.setQq(customer.getQq());
                accountCustomer.setNativePlace(customer.getNativePlace());

                customerService.addCustomer(accountCustomer);
                customer = accountCustomer;
            }
        }

        Set<ProductOrder> productOrders = new HashSet<ProductOrder>(products);
        for (ProductOrder pro : products) {
            pro.setOrder(order);
        }
        order.setProductOrders(productOrders);

        orderService.createOrder(order);
    }

    public void updateProduct() {
        Set<ProductOrder> productOrders = order.getProductOrders();

        List<ProductOrder> list = new ArrayList<ProductOrder>(productOrders);
        for (ProductOrder productOrder : list) {
            if (!products.contains(productOrder)) {
                productOrders.remove(productOrder);
                productOrderService.removeProductOrder(productOrder);
            }
        }

        for (ProductOrder p : products) {
            if (!productOrders.contains(p)) {
                p.setOrder(order);
                productOrders.add(p);
            }
        }

        orderService.updateOrder(order);
    }

    public DataModel getProductTableModel() {
        Collections.sort(products);
        return new ListDataModel(products);
    }

    private void computeAmount() {
        MemberIntegral memberIntegral = memberIntegralService.getMemberIntegral(order.getCustomer());
        double discount = memberIntegral.getDiscount();
        double result = 0d;

        boolean hasGift = false;
        for (ProductOrder p : products) {
            if (p.isGift()) {
                hasGift = true;
                continue;
            }

            result += p.getSubTotal();
        }

        // 折扣原因
        StringBuffer b = new StringBuffer();
        if (discount != 1) {
            b.append(MessageFormat.format("luyuan_crm_member_memberLevel_" + memberIntegral.getMemberLevel().name()));
            b.append("享受").append(discount * 10).append("折。").append("\r\n");
        }
        if (hasGift) {
            b.append("含部分赠品。").append("\r\n");
        }
        order.setRemarks(b.toString());

        order.setAmount(Math.round(result * discount));
    }

    private void computeOldAmount() {
        double result = 0d;
        double price = 0d;
        int count = 0;
        for (ProductOrder pro : products) {
            pro.setName(pro.getProduct().getName());
            pro.setSpecification(pro.getProduct().getSpecification());
            pro.setPrice(pro.getProduct().getPrice());

            price = pro.getProduct().getPrice();
            count = pro.getCount();
            pro.setSubTotal(price * count);

            result += pro.getSubTotal();
        }

        order.setOldAmount(Math.round(result));
    }

    @Override
    public void doCompelete() {
        // 保存单品的订单
        if (order.getId() != null) {
            updateProduct();
            return;
        }
        saveProduct();
    }

    @Override
    public void setActionType(String s) {
    }

    @Override
    public void setStepName(String s) {
        if ("luyuan_crm_sale_confirm_order".equals(s)) {
            computeOldAmount();
            computeAmount();
        }
        else if ("luyuan_crm_sale_write_question".equals(s)) {
            if (StringUtils.isNullOrEmpty(customer.getName())) {
                customer.setName(order.getDelivery().getReceiver());
                customer.setMobile(order.getDelivery().getDeliveryPhone());
            }
            customer.setAddress(order.getDelivery().getDeliveryAddress());
        }
    }

    @Override
    public String getStepName() {
        return null;
    }

    @Override
    public void setWizardName(String s) {
    }

    @Override
    public String getWizardName() {
        return null;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        order = (Order) getRequestAttribute("order");
        if (order != null) {
            orderService.refresh(order);
            customer = customerService.getById(order.getCustomer().getId());
            products.addAll(order.getProductOrders());

            order.getDelivery().getDeliveryPhone();
            customer.getAddress().getCity();
            for (ProductOrder product : products) {
                product.getProduct().getName();
            }

            return;
        }

        order = new Order();
        order.setOrderType(OrderType.SINGLE_PRODUCT);
        order.setDelivery(new Delivery());

        customer = (Customer) getRequestAttribute("customer");
        if (HibernateProxyHelper.getClassWithoutInitializingProxy(customer) == NoAccountCustomer.class) {
            order.setCustomer(((NoAccountCustomer) customer).getAccountHolder());
        }
        else {
            order.setCustomer(customer);
        }

        onCustomerChange();
    }

    public void onCustomerChange() {
        if (customer == null) {
            customer = new Customer();
            customer.setAddress(order.getDelivery().getDeliveryAddress());
            // customer.setName(order.getDelivery().getReceiver());
            // customer.setMobile(order.getDelivery().getDeliveryPhone());
            // customer.setBirthDate(order.getCustomer().getBirthDate());
            // customer.setEmail(order.getCustomer().getEmail());
            // customer.setGender(order.getCustomer().getGender());
            // customer.setHeight(order.getCustomer().getHeight());
            // customer.setWeight(order.getCustomer().getWeight());
            // customer.setQq(order.getCustomer().getQq());
            // customer.setMsn(order.getCustomer().getMsn());
        }

        order.getDelivery().setDeliveryAddress(new Address());
        order.getDelivery().getDeliveryAddress().setCity(customer.getAddress().getCity());
        order.getDelivery().getDeliveryAddress().setPostCode(customer.getAddress().getPostCode());
        order.getDelivery().getDeliveryAddress().setProvince(customer.getAddress().getProvince());
        order.getDelivery().getDeliveryAddress().setRegion(customer.getAddress().getRegion());
        order.getDelivery().getDeliveryAddress().setStreet(customer.getAddress().getStreet());
        order.getDelivery().setReceiver(customer.getName());
        order.getDelivery().setDeliveryPhone(customer.getMobile());
    }

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        if (customer == null && this.customer != null && this.customer.getId() == null) {
            return;
        }
        this.customer = customer;
    }

    public void resetPostCode(ActionEvent event) {
        if (isCustomerEdit()) {
            resetCustomerPostCode();
        }
        else {
            resetDeliveryPostCode();
        }
    }

    private void resetDeliveryPostCode() {
        String province = null, city = null, region = null;
        UIInput uiInput = (UIInput) FacesContext.getCurrentInstance().getViewRoot()
                .findComponent("orderWizard_form:province");
        if (uiInput != null) {
            province = String.valueOf(uiInput.getValue());
        }

        uiInput = (UIInput) FacesContext.getCurrentInstance().getViewRoot().findComponent("orderWizard_form:city");
        if (uiInput != null) {
            city = String.valueOf(uiInput.getValue());
        }

        uiInput = (UIInput) FacesContext.getCurrentInstance().getViewRoot().findComponent("orderWizard_form:region");
        if (uiInput != null) {
            region = String.valueOf(uiInput.getValue());
        }

        Region r = regionService.getByRegion(province, city, region);
        if (r != null) {
            order.getDelivery().getDeliveryAddress().setPostCode(r.getId());
        }
    }

    public void onProvinceChange(ActionEvent event) {
        if (isCustomerEdit()) {
            customer.getAddress().setCity(null);
            customer.getAddress().setRegion(null);
        }
        else {
            order.getDelivery().getDeliveryAddress().setCity(null);
            order.getDelivery().getDeliveryAddress().setRegion(null);
        }
    }

    public void onCityChange(ActionEvent event) {
        if (isCustomerEdit()) {
            customer.getAddress().setRegion(null);
        }
        else {
            order.getDelivery().getDeliveryAddress().setRegion(null);
        }
    }

    private void resetCustomerPostCode() {
        String province = null, city = null, region = null;
        UIInput uiInput = (UIInput) FacesContext.getCurrentInstance().getViewRoot()
                .findComponent("orderWizard_form:province");
        if (uiInput != null) {
            province = String.valueOf(uiInput.getValue());
        }

        uiInput = (UIInput) FacesContext.getCurrentInstance().getViewRoot().findComponent("orderWizard_form:city");
        if (uiInput != null) {
            city = String.valueOf(uiInput.getValue());
        }

        uiInput = (UIInput) FacesContext.getCurrentInstance().getViewRoot().findComponent("orderWizard_form:region");
        if (uiInput != null) {
            region = String.valueOf(uiInput.getValue());
        }

        Region r = regionService.getByRegion(province, city, region);
        if (r != null) {
            order.getDelivery().getDeliveryAddress().setPostCode(r.getId());
        }
    }

    private boolean isCustomerEdit() {
        return null != FacesContext.getCurrentInstance().getViewRoot().findComponent("orderWizard_form:province");
    }

    public boolean isMember() {
        return HibernateProxyHelper.getClassWithoutInitializingProxy(order.getCustomer()) == Member.class;
    }
}
